#pragma once
//objectpool.h
#pragma once
#include <atomic>
#include <iostream>
#include <queue>
#include <vector>
#include <stack>
#include "spinlock.h"

//对象池类
template <class T>
class ObjectPool
{
public:
	T * Pop()
	{
		//SmartLock<SpinLock> mutex(lock_);
		if (pool_.empty())
		{
			T* ptr = new T();
			instances_.push_back(ptr);
			return ptr;
		}
		else
		{
			T* ptr = pool_.top();
			pool_.pop();
			return ptr;
		}
	}
	void Push(T* ptr)
	{
		//SmartLock<SpinLock> mutex(lock_);
		pool_.push(ptr);
	}
	inline std::size_t idle_size()
	{
		return pool_.size();
	}
	inline std::size_t size()
	{
		return instances_.size();
	}
	~ObjectPool()
	{
		for (auto info : instances_)
		{
			delete info;
		}
	}
private:
	//SpinLock lock_;
	std::stack<T*> pool_;
	std::vector<T*> instances_;
};

//对象池使用类，在该变量作用域外，对象会自动返还对象池
template <class TObject>
class SmartObject
{
public:
	SmartObject(ObjectPool<TObject>* pool) :
		pool_(pool),
		pApi_(NULL)
	{
		pApi_ = pool_->Pop();
	}
	~SmartObject()
	{
		pool_->Push(pApi_);
	}
	TObject* operator->()
	{
		return pApi_;
	}
private:
	ObjectPool<TObject>* pool_;
	TObject* pApi_;
};